package com.yumeng.framework.auth.config;

import com.yumeng.common.utils.PathUtils;
import com.yumeng.common.data.enums2.AuthFrame;
import com.yumeng.config.BaseConfiguration;
import com.yumeng.config.helper.EnvHelper;
import com.yumeng.config.properties.YumengAuthProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;

import java.util.ArrayList;
import java.util.List;

/**
 * 基础认证配置文件
 * @author wxd
 * @date 2025/11/10 10:16
 */
@Slf4j
public abstract class BaseAuthConfiguration extends BaseConfiguration {

    protected abstract AuthFrame currAuthFrame();

    //TODO 调整命名来调试 如webMvcProperties2
    protected WebMvcProperties webMvcProperties;
    protected ServerProperties serverProperties;
    protected YumengAuthProperties yumengAuthProperties;
    @Autowired
    public void setWebMvcProperties(WebMvcProperties webMvcProperties) {
        this.webMvcProperties = webMvcProperties;
    }
    @Autowired
    public void setServerProperties(ServerProperties serverProperties) {
        this.serverProperties = serverProperties;
    }
    @Autowired
    public void setYumengProperties(YumengAuthProperties yumengAuthProperties) {
        this.yumengAuthProperties = yumengAuthProperties;
        YumengAuthProperties.YumengBasicProperties.setCurrAuthFrame(currAuthFrame());
        YumengAuthProperties.YumengBasicProperties.setFBS(isFBS());
    }

    /**
     * 是否前后端分离（Frontend-Backend Separation‌）
     * 默认否
     *
     * @return
     */
    protected boolean isFBS(){
        return false;
    }

    //region 通用URL

    //============ security | shiro

    /** 登录Url */
    protected String getLoginUrl(){
        return yumengAuthProperties.getBasic().getLoginUrl();
    }
    /** 登录成功Url */
    protected String getLoginSuccessUrl(){
        return yumengAuthProperties.getBasic().getLoginSuccessUrl();
    }

    //============ shiro
    /** 未认证Url */
    protected String getUnauthorizedUrl(){
        return yumengAuthProperties.getBasic().getUnauthorizedUrl();
    }

    //============ security
    /**
     * 登录处理URL
     */
    protected String getLoginProcessingUrl() {
        return yumengAuthProperties.getBasic().getLoginAction();
    }

    /**
     * sms登录url
     * @return
     */
    protected String getSmsLoginUrl(){
        return yumengAuthProperties.getBasic().getSmsLoginUrl();
    }
    /**
     * sms登录接口
     * @return
     */
    protected String getSmsLoginAction(){
        return yumengAuthProperties.getBasic().getSmsLoginAction();
    }

    /**
     * 登录失败地址
     */
    protected String getLoginFailureUrl() {
        return getCommErrorPageUrl("LoginFailure");
    }
    /**
     * 注销url
     * @return
     */
    protected String getLogoutUrl(){
        return yumengAuthProperties.getBasic().getLogoutUrl();
    }
    /**
     * 注销处理URL
     */
    protected String getLogoutProcessingUrl() {
        return yumengAuthProperties.getBasic().getLogoutAction();
    }
    /**
     * 注销成功URL
     */
    protected String getLogoutSuccessUrl() {
        return getLoginUrl() + "?logout";
    }

    /**
     * 会话失效（失效）URL
     */
    protected String getInvalidSessionUrl() {
        return getCommErrorPageUrl("InvalidSession");
    }

    /**
     * 会话到期URL（在线踢人）
     */
    protected String getExpiredSessionUrl() {
        return getCommErrorPageUrl("ExpiredSession");
    }
    //endregion

    //region 通用配置
    /**
     * 直接放行的URL（默认）
     */
    protected String[] defaultPermitAllUrls() {
        List<String> urls = new ArrayList<>();
        //如果手动指定了static资源路径，可以批量放行；若没有指定，则不批量放行
        //favicon.ico 包含于此，不需要单独设置了
        if (StringUtils.isNotBlank(PathUtils.getStaticPath(webMvcProperties))) {
            urls.add(webMvcProperties.getStaticPathPattern());
        }
        if (CollectionUtils.isNotEmpty(yumengAuthProperties.getBasic().getNeedPermitAllUrls())){
            urls.addAll(yumengAuthProperties.getBasic().getNeedPermitAllUrls());
        }
        //目前仅SECURITY需放开登录url
        //shiro由于默认的登录逻辑，不放开。基于默认FormAuthenticationFilter::onAccessDenied逻辑，登录处理url与登录页面url必须一致
        if (AuthFrame.SECURITY.equals(currAuthFrame())) {
            urls.add(getLoginUrl());//登录地址
        }
        urls.add(getSmsLoginUrl());//短信登录地址
        urls.add(getLogoutUrl());//注销地址
        urls.add(serverProperties.getError().getPath());//异常地址
        urls.add(commErrorPageUrl);//通用异常页面U
        urls.add("/ym/test/**");//用于测试，不要写重要接口

        //TODO 直接放开所有页面访问？
        //filterMap.put("/**/*.vw", "anon");

        //添加接口文档URL过滤规则
        if (EnvHelper.isDev()){
            urls.add("/swagger-ui.html");
            urls.add("/doc.html");
            urls.add("/webjars/**");
            urls.add("/swagger-ui/**");
            urls.add("/swagger-resources/**");
            urls.add("/v3/api-docs/**");
        }
        return urls.toArray(new String[0]);
    }

    //endregion

    //region 私有

    private final String commErrorPageUrl = "/ym/page/error.vw";
    /**
     * 通用异常页面URL
     */
    private String getCommErrorPageUrl(String errMsg) {
        return String.format("%s?errMsg=%s", commErrorPageUrl, errMsg);
    }

    //endregion

}
